// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程：https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129

const { encryptPassword, verifyPassword, generateToken, authMiddleware, refreshToken } = require('aiutils');

module.exports = {
	_before: async function() {
		// 云对象的前置处理函数，每次云对象调用前会执行
		this.db = uniCloud.database();
		this.userCollection = this.db.collection('users');
		this.authResult = null;
		
		// 如果不是登录、注册或刷新token接口，则验证token
		if (!['login', 'register', 'refreshToken'].includes(this.getMethodName())) {
			this.authResult = await authMiddleware(this.getUniCloudRequestEvent(), this.getUniCloudContext());
			
			if (!this.authResult.auth) {
				throw new Error(this.authResult.message);
			}
		}
	},
	
	/**
	 * 用户注册
	 * @param {Object} params
	 * @param {String} params.username - 用户名
	 * @param {String} params.password - 密码
	 * @return {Object} 注册结果
	 */
	async register(params) {
		// 参数校验
		if (!params.username || !params.password) {
			return {
				code: 400,
				message: '用户名和密码不能为空'
			};
		}
		
		try {
			// 检查用户名是否已存在
			const existUser = await this.userCollection.where({
				username: params.username
			}).get();
			
			if (existUser.data.length > 0) {
				return {
					code: 400,
					message: '用户名已存在'
				};
			}
			
			// 加密密码
			const { hash, salt } = encryptPassword(params.password);
			
			// 创建用户
			const result = await this.userCollection.add({
				username: params.username,
				password: hash,
				salt: salt,
				create_time: new Date(),
				update_time: new Date()
			});
			
			if (result.id) {
				// 生成token
				const token = generateToken({
					userId: result.id
				});
				
				return {
					code: 200,
					message: '注册成功',
					data: {
						token,
						userId: result.id,
						username: params.username
					}
				};
			} else {
				return {
					code: 500,
					message: '注册失败'
				};
			}
		} catch (error) {
			console.error('注册失败', error);
			return {
				code: 500,
				message: '注册失败',
				error: error.message
			};
		}
	},
	
	/**
	 * 用户登录
	 * @param {Object} params
	 * @param {String} params.username - 用户名
	 * @param {String} params.password - 密码
	 * @return {Object} 登录结果
	 */
	async login(params) {
		// 参数校验
		if (!params.username || !params.password) {
			return {
				code: 400,
				message: '用户名和密码不能为空'
			};
		}
		
		try {
			// 查询用户
			const userResult = await this.userCollection.where({
				username: params.username
			}).get();
			
			if (userResult.data.length === 0) {
				return {
					code: 404,
					message: '用户不存在'
				};
			}
			
			const user = userResult.data[0];
			
			// 验证密码
			const isPasswordValid = verifyPassword(params.password, user.password, user.salt);
			
			if (!isPasswordValid) {
				return {
					code: 401,
					message: '密码错误'
				};
			}
			
			// 生成token
			const token = generateToken({
				userId: user._id
			});
			
			// 更新最后登录时间
			await this.userCollection.doc(user._id).update({
				last_login_time: new Date()
			});
			
			return {
				code: 200,
				message: '登录成功',
				data: {
					token,
					userId: user._id,
					username: user.username
				}
			};
		} catch (error) {
			console.error('登录失败', error);
			return {
				code: 500,
				message: '登录失败',
				error: error.message
			};
		}
	},
	
	/**
	 * 获取用户信息
	 * @return {Object} 用户信息
	 */
	async getUserInfo() {
		// 前置处理函数中已经验证了token，这里直接返回用户信息
		return {
			code: 200,
			message: '获取成功',
			data: this.authResult.user
		};
	},
	
	/**
	 * 更新用户信息
	 * @param {Object} params - 要更新的用户信息
	 * @return {Object} 更新结果
	 */
	async updateUserInfo(params) {
		// 不允许更新敏感信息
		delete params.password;
		delete params.salt;
		delete params._id;
		
		try {
			const userId = this.authResult.user._id;
			
			// 更新用户信息
			await this.userCollection.doc(userId).update({
				...params,
				update_time: new Date()
			});
			
			return {
				code: 200,
				message: '更新成功'
			};
		} catch (error) {
			console.error('更新用户信息失败', error);
			return {
				code: 500,
				message: '更新失败',
				error: error.message
			};
		}
	},
	
	/**
	 * 修改密码
	 * @param {Object} params
	 * @param {String} params.oldPassword - 旧密码
	 * @param {String} params.newPassword - 新密码
	 * @return {Object} 修改结果
	 */
	async changePassword(params) {
		if (!params.oldPassword || !params.newPassword) {
			return {
				code: 400,
				message: '旧密码和新密码不能为空'
			};
		}
		
		try {
			const userId = this.authResult.user._id;
			
			// 查询用户完整信息（包含密码和盐值）
			const userResult = await this.userCollection.doc(userId).get();
			
			if (userResult.data.length === 0) {
				return {
					code: 404,
					message: '用户不存在'
				};
			}
			
			const user = userResult.data[0];
			
			// 验证旧密码
			const isPasswordValid = verifyPassword(params.oldPassword, user.password, user.salt);
			
			if (!isPasswordValid) {
				return {
					code: 401,
					message: '旧密码错误'
				};
			}
			
			// 加密新密码
			const { hash, salt } = encryptPassword(params.newPassword);
			
			// 更新密码
			await this.userCollection.doc(userId).update({
				password: hash,
				salt: salt,
				update_time: new Date()
			});
			
			return {
				code: 200,
				message: '密码修改成功'
			};
		} catch (error) {
			console.error('修改密码失败', error);
			return {
				code: 500,
				message: '修改密码失败',
				error: error.message
			};
		}
	},
	
	/**
	 * 刷新token
	 * @param {Object} params
	 * @param {String} params.token - 旧的token
	 * @return {Object} 刷新结果
	 */
	async refreshToken(params) {
		// 参数校验
		if (!params.token) {
			return {
				code: 400,
				message: 'token不能为空'
			};
		}
		
		try {
			// 刷新token
			const result = refreshToken(params.token);
			
			if (result.success) {
				return {
					code: 200,
					message: '刷新成功',
					data: {
						token: result.token
					}
				};
			} else {
				return {
					code: 401,
					message: result.message
				};
			}
		} catch (error) {
			console.error('刷新token失败', error);
			return {
				code: 500,
				message: '刷新token失败',
				error: error.message
			};
		}
	}
};
